/*
 * Copyright 2007 Brian Watkins
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package bw.cal;

import java.text.*;
import java.util.*;
import java.io.Serializable;

import bw.util.Log;

public class CalendarEventTime implements Serializable, Comparable
{
    private static SimpleDateFormat _format = new SimpleDateFormat( "yyyy-MM-dd hh:mm aa" );
    private static SimpleDateFormat _timeFormat = new SimpleDateFormat( "h:mmaa" );

    private Date _start = null;
    private Date _end = null;

    public static CalendarEventTime construct ( String dateStr, 
                                                String startStr, String endStr )
    {
        String start = dateStr + " " + fixTime( startStr );
        String end = dateStr + " " + fixTime( endStr );

        Date startDate = null;
        Date endDate = null;

        try 
        {
            startDate = _format.parse( start );
            endDate = _format.parse( end );
        }
        catch ( ParseException ex )
        {
            //should never happen!??!
            Log.getInstance().write( "Could not parse dates: " + start + ", " + end, ex );
        }

        return new CalendarEventTime( startDate, endDate );
    }

    private static String fixTime ( String timeStr )
    {
        String time = "00:00 am";

        if ( timeStr != null && timeStr.length() > 0 )
        {
            int i = -1;
            if ( ( i = timeStr.toLowerCase().indexOf( "am" ) ) == -1 )
            {
                i = timeStr.toLowerCase().indexOf( "pm" );
            }
            
            String t = timeStr.substring( 0, i ).trim();
            String a = timeStr.substring( i ).trim();
            
            if ( t.indexOf( ":" ) == -1 )
            {
                t += ":00";
            }
            
            time = ( t + " " + a );
        }

        return time;
    }

    public CalendarEventTime ( Date start, Date end )
    {
        _start = start;
        _end = end;
    }

    public Date getStart () { return _start; }

    public Date getEnd () { return _end; }

    public String getStartTimeStr ()
    {
        return _timeFormat.format( _start ).toLowerCase();
    }

    public String getEndTimeStr ()
    {
        return _timeFormat.format( _end ).toLowerCase();
    }

    public String toString ()
    {
        return _format.format( _start ) + " - " + _format.format( _end );
    }

    public boolean equals ( Object obj )
    {
        return this.toString().equals( ( (CalendarEventTime) obj ).toString() );
    }

    public int compareTo ( Object obj )
    {
        CalendarEventTime cet = (CalendarEventTime) obj;

        //note calendar event time really should only know about
        //the time of day -- even though we store this in date objects 
        //which contain also the date as well. problem is with weekly 
        //events this throws off the ordering.
        //so we need to simply compare the TIMES when comparing two 
        //CalendarEventTIME objects.
        //But how can we do that slickly? 
        //Take the time in millis and mod by the number of millis in a day.
        //that gives you the number of millis in whatever day it is.
        
        long millisInDay = 24*60*60*1000L; 

        //first check the start dates
        Long myStart = new Long( _start.getTime() % millisInDay );
        Long yrStart = new Long( cet.getStart().getTime() % millisInDay );

        int ct = myStart.compareTo( yrStart );
        if ( ct == 0 ) 
        {
            //check the end dates. sort above if ends earlier
            Long myEnd = new Long( _end.getTime() % millisInDay );
            Long yrEnd = new Long( cet.getEnd().getTime() % millisInDay );
            ct = myEnd.compareTo( yrEnd );
        }

        return ct;
    }

}